#include "ProgramManager.hpp"
#include "CallingContext.hpp"
#include "CallingInstance.hpp"

#include "Call.hpp"
#include "Memory.hpp"
#include "CallingInstance.hpp"
#include "CallingContext.hpp"
#include "ProgramManager.hpp"

Call::Call( const std::string& name, std::vector < Expression* > listeExpression )
{
  _name=name;
  _listeExpression=listeExpression;
}

Call::~Call ()
{
}

void Call::compute ()
{
  LOGFUNCTION(IEXEC_LOG);
  CallingInstance *ci;
  CallingContext *cc;
  cc=ProgramManager::getCallingContext(ProgramManager::getIndexOf(_name));
  ci=cc->getInstance(ProgramManager::getCurrentInstance());
  Memory *memoire = ci->getMemory();
  int addresse;

  for (unsigned int it=0;it<_listeExpression.size();it++){
    _listeExpression[it]->compute();
    ExpressionValue value=_listeExpression[it]->getValue();
    addresse=ci->getAddress(cc->getParameterIndex(it));    
    switch ( value._type._modifier )
      {
      case NONE:
	switch ( value._type._base )
	  {
	  case INTEGER:
	    memoire->set ( addresse, (void*) &value._value._vinteger, getTypeSize(value._type));
	    break;
	  case REAL:
	    memoire->set ( addresse, (void*) &value._value._vreal, getTypeSize ( value._type ) );
	    break;
	  case BOOLEAN:
	    memoire->set ( addresse, (void*) &value._value._vboolean, getTypeSize ( value._type ) );
	    break;
	  case STRING:
	    break;
	  default:
	    break;
	  }
	break;
      case POINTER:
	if ( value._type._base != STRING )
	  {
	    memoire->set ( addresse, (void*) &value._value._vaddress, getTypeSize ( value._type ) );
	  }
	break;
      case ARRAY:
	break;
      default:
	break;
      }
  }
  ci->execute();
}

void Call::display ( const unsigned int shift) const
{
  std::cout << _name << "(";
  for (unsigned int it=0;it<_listeExpression.size();it++){
    if (it!=0) std::cout << ",";
    _listeExpression[it]->display(shift);
  }
  std::cout << ")\n";
}
